<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
  
  <title>date-demo</title>
  <style>
    body{
      display: flex;
      flex-wrap: wrap;
      justify-content: center ;
    }
  </style>
</head>
<body>
  <label for="meeting">h5原生日期：</label><input id="meeting" type="date" min="1949-01-01" value="2014-01-13"/>
  <div style="width: 100vw;margin: 20px auto;background-color:antiquewhite;display: flex;justify-content: center;">
    <div class="mi-date">
      <input class="mi-date-year" type="text" data-datetype="date" data-format="yyyy/MM/dd" onkeypress="return event.keyCode>=48&&event.keyCode<=57" autocomplete="off" value="2012/12/12">
      <input class="mi-date-year" type="text" data-datetype="datetime" data-format="yyyy/MM/dd" onkeypress="return event.keyCode>=48&&event.keyCode<=57" autocomplete="off" value="2012/12/13 00:00:00">
    </div>
  </div>
  <div id="test">6666688899</div>
  <script src="./mi-date.js"></script>
  <script>
    $('.mi-date-year').on('keydown input paste',function(event) {
      console.log('???:',event.type)
      if (event.type == 'paste') {
        // event.clipboardData.getAsString(text => {
          console.log("复制的文字：",event.originalEvent.clipboardData.getData('text/plain'));  //  在控制台输出剪贴板中的文本
        // });
        let rqV = event.originalEvent.clipboardData.getData('text/plain').replace(/[^\d]/g, '');
        console.log("rqv",rqV,judgeRQIsValid(rqV, $(this).attr('data-datetype')))
        if (judgeRQIsValid(rqV, $(this).attr('data-datetype'))) {
          let pasteStr = event.originalEvent.clipboardData.getData('text/plain');
          console.log("日期粘贴：", rqV,transformDate(rqV, $(this).attr('data-datetype')))
          setTimeout(() => {
            // $(this).val(transformDate(rqV, $(this).attr('data-datetype')))
            $(this).val(formatDate(rqV, $(this).attr('data-format')))
          }, 10)
        } else {
          return false;
        }
        event.preventDefault;
      }
      if (event.type == 'input') { // 去除中文输入法可以输入中文
        console.log("input!!!!!$(this).val:", $(this).val(), ',$(this).val().replace(/[^\d|\.]/g, ""):', $(this).val().replace(/[^\d|\.]/g, ''))
        setTimeout(() => {
            $(this).val($(this).val().replace(/[^\d|\/]/g, ''));
        },100)
      }
      let nowPos = getCursortPosition(event);
      console.log(event.key, event.keyCode,nowPos)
      let rqV = $(this).val().split('');
      if (event.key == 'Backspace') { // 删除键删除时置为0或1
        if (nowPos.start - 1 >= 0) {
          nowPos.start = nowPos.start-1;
          nowPos.end = nowPos.end-1;
          if (/\d/.test(rqV[nowPos.start])) {
            rqV[nowPos.start] = 0;
            $(this).val(rqV.join(''))
          }
          setInputPosition($(this)[0], nowPos)
        }
        event.preventDefault();
      } else if (/\d/.test(event.key)) {
        console.log("keydown!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
        if (/\d/.test(rqV[nowPos.start])) {
          console.log("当前位置为数字，放行")
          rqV[nowPos.start] = event.key;
          
          let nextJump = 1; // 下一跳距离
          
          if(nowPos.start == 5 && event.key >= 2) { // 处理月份
            rqV[nowPos.start] = 0;
            rqV[nowPos.start + 1] = event.key;
            nextJump = 3;
          } else if (nowPos.start == 5 && event.key == 1) {
            rqV[nowPos.start + 1] > 2 ? rqV[nowPos.start + 1] = 0 : '';
          } else if (nowPos.start == 6 && event.key > 2) {
            rqV[nowPos.start - 1] = 0;
          } else if (nowPos.start == 8 && event.key > 3) { // 处理日期
            rqV[nowPos.start] = 0;
            rqV[nowPos.start + 1] = event.key;
            nextJump = 2
          } else if (nowPos.start == 8 || nowPos.start == 9) {
            // getDayByYear(rqV.join('').substring(0,4)*1, rqV.join('').substring(5,7)*1) < Number(rqV[8]+rqV[9]) ? rqV[nowPos.start + 1] = 0 : ''
            let days = getDayByYear(rqV.join('').substring(0,4)*1, rqV.join('').substring(5,7)*1)
            if (days < Number(rqV[8]+rqV[9])) {
              rqV[8] = (days+'').split('')[0]
              rqV[9] = (days+'').split('')[1]
            }
          } else if (nowPos.start == 9) {
           
          }
          // let day =  getDayByYear(rqV.join('').substring(0,4)*1, rqV.join('').substring(5,7)*1)
          // console.log('test:',((day+'').substring(1)),day)
          // day < Number(rqV[8]+rqV[9]) ? (rqV[9] = ((day+'').substring(1))) && (rqV[8] = ((day+'').substring(0,1))) : '';
          if (nowPos.start == 3 || nowPos.start == 6) {
            nextJump = 2
          }
          $(this).val(rqV.join(''))
          nowPos.start = nowPos.start+nextJump;
          nowPos.end = nowPos.end+nextJump;
          setInputPosition($(this)[0], nowPos)
        }
        event.preventDefault();
      }
    })
/**
* @method  获取光标位置
* @param {Object} [e] 当前事件对象
*/
function getCursortPosition(e) {
    let pos = {start:0, end: 0};
    pos = getPosition(e.target);
    return pos;
}

// 输入框获取光标位置
function getPosition(element) {
    let cursorPos = {start:0, end: 0};
    // IE
    if (document.selection) {
       throw("不支持ie")
    } else if (element.selectionStart || element.selectionStart == '0') {
      cursorPos = {start:element.selectionStart, end: element.selectionEnd};
    }
    return cursorPos;
}

// 设置光标位置 input/textarea
function setInputPosition(textDom, pos) {
    console.log("设置光标位置：", pos,",textDom:",textDom,textDom.createTextRange,textDom.setSelectionRange)
    if (textDom.setSelectionRange) {
        // IE Support
        textDom.focus();
        textDom.setSelectionRange(pos.start, pos.end);
    } else if (textDom.createTextRange) {
        // Firefox support
        var range = textDom.createTextRange();
        range.collapse(true);
        range.moveEnd('character', pos.start);
        range.moveStart('character', pos.end);
        range.select();
        console.log("光标！！！！")
    }
}

/**
* @method  日期 单个数字输入后 下一跳光标位置
* @param {string} [rqv] 当前日期输入框的值
* @param {object} [nowPos] 当前光标的位置 eg: {start: 0, end: 0}
*/
function rqNextJump(rqv, nowPos) {

}

/**
* @method  获取年份天数
* @param {number} [year] 年份
* @param {number} [month] 月份
*/
function getDayByYear(year, month) {
  if(year == undefined)
    return
  let isRN = ((year % 4 == 0) && (year % 100 != 0)) || ((year % 100 == 0) && (year % 400 == 0) )
  let days = 30
  switch(month) {
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
      days = 31
      break;
    case 2:
      isRN == true ? days = 29 : days = 28
      break;
  }
  return days;
}
/**
* @method  判断日期是否合法
* @param {number} [rqV] 日期值 eg: 20120606121212
* @param {number} [type] year month date datetime
*/
function judgeRQIsValid(rqV, type) {
  rqV = rqV.replace(/[^\d]/g, '');
  let isValid = false;
  switch(type) {
    case 'year':
      isValid = rqV.length == 4 ? true : false;
      break;
    case 'month':
      isValid = (rqV.length == 6 && rqV.substring(4,6)*1<13) ? true : false;
      break;
    case 'date':
      isValid = (rqV.length == 8 && rqV.substring(4,6)*1<13 && getDayByYear(rqV.substring(1,4)*1,rqV.substring(4,6)*1) >= rqV.substring(6,8)) ? true : false;
      break;
    case 'datetime':
      isValid = (rqV.length == 14 && rqV.substring(4,6)*1<13 && getDayByYear(rqV.substring(1,4)*1,rqV.substring(4,6)*1) >= rqV.substring(6,8) && rqV.substring(8, 10)*1 < 24 && rqV.substring(10, 12)*1 < 60 && rqV.substring(12, 14)*1 < 60) ? true : false;
      break;
  }
  return isValid;
}
/**
* @method 日期格式化
* @param {number} [rqV] 日期值 eg: 20120606121212
* @param {number} [type] year date datetime
* @param {string} [format] 日期格式 yyyy-MM-dd hh:mm:ss
*/
function transformDate(rqV, type, splitStr = '') {
  if(rqV == undefined || type == undefined) {
    return
  }
  let format = '';
  switch(type) {
    case 'year':
      format = rqV.split('')
      format.splice(4, 0, splitStr)
      break;
    case 'date':
      format = rqV.split('');
      format.splice(4, 0, splitStr)
      format.splice(7, 0, splitStr)
      break;
    case 'datetime':
      format = rqV.split('')
      format.splice(4, 0, splitStr);
      format.splice(7, 0, splitStr);
      format.splice(10, 0, ' ');
      format.splice(13, 0, ':');
      format.splice(16, 0, ':');
      break;
  }
  return format.join('')
}

/**
* @method 日期格式化
* @param {number} [type] year date datetime
* @param {string} [dateString] 日期值 eg: 20120606121212
* @param {string} [format] 日期格式 yyyy-MM-dd hh:mm:ss
*/
function formatDate(dateString, format = 'yyyy-MM-dd hh:mm:ss') {
  var year = dateString.substring(0, 4) * 1;
  var month = dateString.substring(4, 6) * 1 > 1 ? dateString.substring(4, 6) * 1 - 1 : 0;
  var day = dateString.substring(6, 8) * 1;
  var hours = dateString.substring(8, 10) * 1;
  var minutes = dateString.substring(10, 12) * 1;
  var seconds = dateString.substring(12, 14) * 1;
  var date = new Date(year, month, day, hours, minutes, seconds);
  var o = {
    "M+": date.getMonth() + 1, // month
    "d+": date.getDate(), // day
    "h+": date.getHours(), // hour
    "m+": date.getMinutes(), // minute
    "s+": date.getSeconds(), // second
  };
  var matchArr = []; // 辅助变量
  if (/(y+)/.test(format)) {
    matchArr = format.match(/(y+)/)
    format = format.replace(matchArr[0], (date.getFullYear() + "").substring(4 - matchArr[0].length));
  }

  for (var k in o) {
    if (new RegExp("(" + k + ")").test(format)) {
      matchArr = format.match(new RegExp("(" + k + ")"))
      format = format.replace(matchArr[0], matchArr[0].length == 1 ? o[k] : ("00" + o[k]).substring(("" + o[k]).length));
    }
  }
  console.log("format:",format)
  return format;
}
  </script>
</body>
</html>